package com.jk1123.us.core.id;

import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class IdContainer {
    private final int STATE_EMPTY = 0;
    private final int STATE_FILLING = 1;
    private final int STATE_FULL = 2;
    private final int STATE_SWAP = 3;
    private volatile int state = STATE_EMPTY;
    private static final int CAPACITY = 100000;
    /**
     * 阈值
     */
    private float threshold = 0.5f;
    private Queue<Long> current = new ArrayDeque<>(CAPACITY);
    private Queue<Long> next = new ArrayDeque<Long>(CAPACITY);

    private Random random = new Random();
    private Executor FillThread = Executors.newSingleThreadExecutor();
    private CountDownLatch latch;

    public void init() {

        for (int i = 0; i < CAPACITY; i++) {
            current.add(random.nextLong());
        }
    }

    private void switchContainer() {
        //如果是填充状态 就等待
        if (state == STATE_FILLING) {
            try {
                //等待填充完毕
                latch.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //
        //说明 已经准备好了 用就完事了
        current = next;
        next = new ArrayDeque<>(CAPACITY);
        state = STATE_SWAP;

    }


    private void checkRemainder() {
        if (current.size() < CAPACITY * threshold) {
            //检查是否还有充足的余量
            //只有next为空的时候 才触发
            if (state == STATE_EMPTY||state==STATE_SWAP) {
                //说明替换过了
                latch = new CountDownLatch(1);
                state = STATE_FILLING;
                FillThread.execute(new Runnable() {
                    @Override
                    public void run() {

                        for (int i = 0; i < CAPACITY; i++) {
                            next.add((long) random.nextInt(10));
                        }

                        state = STATE_FULL;
                        latch.countDown();
                    }
                });
            }


        }
    }

    public synchronized Long next() {
        if (current.isEmpty()) {
            //为空了 需要替换
            switchContainer();
        }
        Long result = current.poll();
        //这里处理百分比
        checkRemainder();
        return result;
    }

    public static void main(String[] args) {
        Bucket bucket = new Bucket(10);
        Long[] arr=new Long[10];
        for (int i = 0; i<10; i++){
            bucket.put((long) i);
        }

        bucket.shuffle();
        for (int i=0;i<100;i++){
            if (!bucket.isEmpty()){
                Long take = bucket.take();
                System.out.println(take);
            }


        }

    }
    private static class Bucket{
        private int capacity;
        private Long[] slots;

        private int putIndex;

        private int takeIndex;

        private Random random=new Random();

        public Bucket(int capacity) {
            this.capacity=capacity;
            this.slots=new Long[capacity];
        }



        public boolean isEmpty(){
            return takeIndex>=putIndex?true:false;
        }
        public Long put(Long l){

            return slots[putIndex++]=l;
        }
        public Long take(){

            return slots[takeIndex++];
        }
        public void shuffle(){
            int size=slots.length;
            for (int i=size; i>1; i--){
                swap(slots, i-1, random.nextInt(i));
            }
        }
        private  void swap(Object[] arr, int i, int j) {
            Object tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }


    }
}
